1
|
|
package net.sf.flock.impl;
|
2
|
|
|
3
|
|
import java.io.File;
|
4
|
|
import java.io.FileInputStream;
|
5
|
|
import java.io.FileOutputStream;
|
6
|
|
import java.io.IOException;
|
7
|
|
import java.io.ObjectInputStream;
|
8
|
|
import java.io.ObjectOutputStream;
|
9
|
|
import java.io.OutputStreamWriter;
|
10
|
|
import java.io.Writer;
|
11
|
|
import java.net.URL;
|
12
|
|
import java.util.List;
|
13
|
|
|
14
|
|
import net.sf.flock.FlockResourceException;
|
15
|
|
import net.sf.flock.SubscriptionI;
|
16
|
|
import net.sf.flock.SubscriptionInfoI;
|
17
|
|
import net.sf.flock.support.OpmlSubscriptionExport;
|
18
|
|
import net.sf.flock.support.OpmlSubscriptionImport;
|
19
|
|
import org.apache.log4j.LogManager;
|
20
|
|
import org.apache.log4j.Logger;
|
21
|
|
import org.jdom.Document;
|
22
|
|
import org.jdom.JDOMException;
|
23
|
|
import org.jdom.input.SAXBuilder;
|
24
|
|
import org.jdom.output.XMLOutputter;
|
25
|
|
|
26
|
|
/**
|
27
|
|
*
|
28
|
|
* @version $Revision: 1.7 $
|
29
|
|
* @author $Author: zombi $
|
30
|
|
*/
|
31
|
|
public class PersistentSubscriptionManager extends SimpleSubscriptionManager {
|
32
|
|
|
33
|
|
private final static Logger LOGGER = LogManager.getLogger(PersistentSubscriptionManager.class);
|
34
|
|
|
35
|
|
private final File storeDirectory;
|
36
|
|
|
37
|
0
|
public PersistentSubscriptionManager(File storeDirectory) throws FlockResourceException {
|
38
|
0
|
this.storeDirectory = storeDirectory;
|
39
|
0
|
this.initStore();
|
40
|
|
}
|
41
|
|
|
42
|
|
/**
|
43
|
|
* @see net.sf.flock.impl.SimpleSubscriptionManager#refresh(net.sf.flock.SubscriptionI)
|
44
|
|
*/
|
45
|
0
|
protected List refresh(SubscriptionI subscription) throws FlockResourceException {
|
46
|
0
|
List l = super.refresh(subscription);
|
47
|
0
|
if (l.size()>0) {
|
48
|
0
|
this.storeSubscription(subscription);
|
49
|
|
}
|
50
|
0
|
return l;
|
51
|
|
}
|
52
|
|
|
53
|
0
|
public SubscriptionI[] subscribe(SubscriptionInfoI si, boolean loadFeed) throws FlockResourceException {
|
54
|
0
|
SubscriptionI[] subscriptions = super.subscribe(si, loadFeed);
|
55
|
0
|
this.saveSubscriptions();
|
56
|
0
|
return subscriptions;
|
57
|
|
}
|
58
|
|
|
59
|
|
/**
|
60
|
|
* @see net.sf.flock.SubscriptionManagerI#unsubscribe(java.net.URL)
|
61
|
|
*/
|
62
|
0
|
public void unsubscribe(URL url) throws FlockResourceException {
|
63
|
0
|
super.unsubscribe(url);
|
64
|
|
|
65
|
0
|
this.saveSubscriptions();
|
66
|
|
|
67
|
0
|
File feedFile = this.getFeedFile(url);
|
68
|
0
|
feedFile.delete();
|
69
|
|
}
|
70
|
|
|
71
|
|
|
72
|
0
|
protected void initStore() throws FlockResourceException {
|
73
|
|
|
74
|
0
|
if (!this.storeDirectory.exists()) {
|
75
|
0
|
LOGGER.info("First run - creating directory " + this.storeDirectory);
|
76
|
0
|
if (!this.storeDirectory.mkdir()) {
|
77
|
0
|
throw new FlockResourceException("Unable to create directory "+storeDirectory);
|
78
|
|
}
|
79
|
|
}
|
80
|
|
|
81
|
0
|
File storeFile = new File(storeDirectory, "flock.opml");
|
82
|
0
|
if (!storeFile.exists()) {
|
83
|
0
|
LOGGER.info("No flock.opml - create");
|
84
|
0
|
this.saveSubscriptions();
|
85
|
0
|
return;
|
86
|
|
}
|
87
|
|
|
88
|
0
|
Document doc;
|
89
|
0
|
try {
|
90
|
0
|
doc = new SAXBuilder().build(storeFile);
|
91
|
|
} catch (JDOMException e) {
|
92
|
0
|
throw new FlockResourceException("Unable to load store file "+storeFile, e);
|
93
|
|
}
|
94
|
|
|
95
|
0
|
SubscriptionInfoI[] subs = new OpmlSubscriptionImport().load(doc);
|
96
|
0
|
for (int i=0; i<subs.length; i++) {
|
97
|
0
|
try {
|
98
|
0
|
this.addSubscription(
|
99
|
|
this.loadSubscription(subs[i].getLocation())
|
100
|
|
);
|
101
|
|
} catch (FlockResourceException e) {
|
102
|
0
|
LOGGER.warn("Failed to load subscription contents: " + e);
|
103
|
0
|
super.subscribe( subs[i], false );
|
104
|
|
}
|
105
|
|
}
|
106
|
|
|
107
|
|
}
|
108
|
|
|
109
|
|
/** Save subscription list as OPML */
|
110
|
0
|
protected void saveSubscriptions() throws FlockResourceException {
|
111
|
0
|
Document doc = new OpmlSubscriptionExport().export( this.getSubscriptions() );
|
112
|
0
|
XMLOutputter outputter = new XMLOutputter(" ", true);
|
113
|
0
|
File storeFile = new File(storeDirectory, "flock.opml");
|
114
|
0
|
try {
|
115
|
0
|
Writer writer = new OutputStreamWriter( new FileOutputStream(storeFile), "UTF8");
|
116
|
0
|
outputter.output(doc, writer);
|
117
|
0
|
writer.close();
|
118
|
|
} catch (IOException e) {
|
119
|
0
|
throw new FlockResourceException("Unable to save store file "+storeFile, e);
|
120
|
|
}
|
121
|
|
}
|
122
|
|
|
123
|
|
|
124
|
|
|
125
|
0
|
protected SubscriptionI loadSubscription(URL location) throws FlockResourceException {
|
126
|
|
|
127
|
0
|
File feedFile = this.getFeedFile(location);
|
128
|
0
|
if (!feedFile.exists()) {
|
129
|
0
|
throw new FlockResourceException("No subscription stored for "+location);
|
130
|
|
}
|
131
|
0
|
try {
|
132
|
0
|
ObjectInputStream ois = new ObjectInputStream( new FileInputStream(feedFile) );
|
133
|
0
|
SubscriptionI sub = (SubscriptionI)ois.readObject();
|
134
|
0
|
ois.close();
|
135
|
|
|
136
|
0
|
return sub;
|
137
|
|
|
138
|
|
} catch (ClassNotFoundException e) {
|
139
|
0
|
throw new FlockResourceException(e);
|
140
|
|
} catch (IOException e) {
|
141
|
0
|
throw new FlockResourceException(e);
|
142
|
|
}
|
143
|
|
|
144
|
|
}
|
145
|
|
|
146
|
0
|
protected void storeSubscription(SubscriptionI subscription) throws FlockResourceException {
|
147
|
0
|
File feedFile = this.getFeedFile(subscription.getLocation());
|
148
|
0
|
ObjectOutputStream oos;
|
149
|
0
|
try {
|
150
|
0
|
oos = new ObjectOutputStream(new FileOutputStream(feedFile));
|
151
|
0
|
oos.writeObject(subscription);
|
152
|
0
|
oos.close();
|
153
|
|
} catch (IOException e) {
|
154
|
0
|
throw new FlockResourceException(e);
|
155
|
|
}
|
156
|
|
}
|
157
|
|
|
158
|
0
|
private File getFeedFile(URL url) {
|
159
|
0
|
return new File(this.storeDirectory, "feed"+url.hashCode() + ".ser" );
|
160
|
|
}
|
161
|
|
|
162
|
|
}
|
163
|
|
|